---
title: Creating a Custom Apollo Router Core Binary
subtitle: Compile a custom router binary from source
description: Compile a custom Apollo Router Core binary from source. Learn to create native Rust plugins.
---

import ElasticNotice from '../../../shared/elastic-notice.mdx';
import NativePluginNotice from '../../../shared/native-plugin-notice.mdx';

Learn how to compile a custom binary from Apollo Router Core source, which is required to create custom native Rust plugins for the router.

<NativePluginNotice />

<ElasticNotice />

## Prerequisites

<!-- renovate-automation: rustc version -->
To compile the router, you need to have [Rust 1.91.1 or later](https://www.rust-lang.org/tools/install) installed.

## 1. Create a new project

1. Use the `cargo new` command to create a project for your custom router:

   ```bash
   cargo new --bin starstuff
   ```

For the purposes of this tutorial, set your project's name to `starstuff`.

2. After your project is created, change to the `starstuff` directory:

   ```bash
   cd starstuff
   ```

Write the source code for your custom binary.

## 2. Compile the router

Create a debug build of the router with the following command:

```bash
cargo build
```

The resulting debug binary is located in `target/debug/router`.

To create a release build for production environments, use this command instead:

```bash
cargo build --release
```

The resulting release binary is now located in `target/release/router`.

## 3. Run the compiled binary

Now you can test out your compiled router with an example supergraph schema.

1. Download the example schema with the following command:

   ```bash
   curl -sSL https://supergraph.demo.starstuff.dev/ > supergraph-schema.graphql
   ```

2. Run the router and provide the example schema like so:

   ```bash
   cargo run -- --hot-reload --config router.yaml --supergraph supergraph-schema.graphql
   ```

   During development, it's helpful to use `cargo run` to run the router.

If you're using managed federation, you set the `APOLLO_KEY` and `APOLLO_GRAPH_REF` environment variables instead of specifying the supergraph schema as a file. For details, see [this section](/federation/managed-federation/setup#4-connect-your-router-to-graphos).

## 4. Create a plugin

1. From within your project directory, implement your new plugin.

2. Add configuration options for the created plugin to your `router.yaml` file:

   ```yaml  title="router.yaml"
   plugins:
     starstuff.hello_world:
       message: "starting my plugin"
   ```

3. Run the router again:

    ```bash
    cargo run -- --hot-reload --config router.yaml --supergraph supergraph-schema.graphql
    ```

    This time, you should see a log line like the following:

    ```bash
    2022-05-21T09:16:33.160288Z  INFO router::plugins::hello_world: starting my plugin
    ```

Nice work! You now have a custom router binary with an associated plugin. Next, you can extend the plugin with the functionality you need or add more plugins.

## Memory allocator

On Linux the `apollo-router` crate sets [jemalloc](http://jemalloc.net/)
as [the global memory allocator for Rust](https://doc.rust-lang.org/std/alloc/index.html#the-global_allocator-attribute)
to reduce memory fragmentation.
Future versions may do so on more platforms, or switch to yet a different allocator.
This is enabled by default and controlled by a `global-allocator` Cargo feature flag.
If you want to choose a different allocator, disable it in your `Cargo.toml`:

```toml
[dependencies]
apollo-router = {version = "[…]", default-features = false}
```

If you make a library crate, also specify `default-features = false`
in order to leave the choice open for the eventual executable crate.
(Cargo default features are only disabled if *all* dependents specify `default-features = false`.)

## Related topics

* [Optimizing Custom Router Builds](/graphos/routing/self-hosted/containerization/optimize-build)
